package com.leizi.igym.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leizi.igym.constant.CategoryConstant;
import com.leizi.igym.domain.Category;
import com.leizi.igym.dto.CategoryAddDTO;
import com.leizi.igym.dto.CategoryDTO;
import com.leizi.igym.dto.CategoryPageQueryDTO;
import com.leizi.igym.enums.ReturnCodeEnum;
import com.leizi.igym.exception.BusinessException;
import com.leizi.igym.mapper.CategoryMapper;
import com.leizi.igym.resp.PageResult;
import com.leizi.igym.service.CategoryService;
import com.leizi.igym.utils.ThrowUtils;
import com.leizi.igym.vo.CategoryCascaderVO;
import com.leizi.igym.vo.CategoryVO;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author PC
 * @description 针对表【t_category(分类总表)】的数据库操作Service实现
 * @createDate 2024-04-07 17:57:07
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {

    @Resource
    private CategoryMapper categoryMapper;

    @Override
    public boolean saveParentCategoryWithChild(CategoryAddDTO dto) {
        if (dto == null) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }
        Category category = new Category();
        if (category.getParentId() == null) {
            category.setParentId(CategoryConstant.TOP_CATEGORY_PARENT_ID);
        }
        BeanUtils.copyProperties(dto, category);
        List<CategoryAddDTO> childList = dto.getChildList();
        Integer result = this.getBaseMapper().insert(category);
        if (CollectionUtil.isEmpty(childList)) {
            return null != result && result >= 1;
        }

        List<Category> categoryList = childList.stream().map(child -> {
            Category childCategory = new Category();
            childCategory.setParentId(category.getId());
            BeanUtils.copyProperties(child, childCategory);
            return childCategory;
        }).toList();


        return this.saveBatch(categoryList);
    }

    @Override
    public boolean removeCategory(Long id) {
        if (id == null || id <= 0) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }

        Category dbCategory = this.getBaseMapper().selectById(id);

        if (Objects.isNull(dbCategory)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }
        Long parentId = dbCategory.getParentId();
        if (CategoryConstant.TOP_CATEGORY_PARENT_ID.equals(parentId)) {
            QueryWrapper<Category> qw = new QueryWrapper<>();
            qw.eq("parent_id", id);
            this.getBaseMapper().delete(qw);
        }
        Integer result = this.getBaseMapper().deleteById(id);
        return null != result && result >= 1;
    }

    @Override
    public boolean updateCategory(CategoryDTO dto) {
        ThrowUtils.throwIf(Objects.isNull(dto), ReturnCodeEnum.PARAMS_ERROR);
        Long id = dto.getId();
        List<Category> childCategory = dto.getChildCategory();
        if (CollectionUtil.isNotEmpty(childCategory)) {
            // 如法炮制，先删后加 -> 修改为：因为我们有其id值还是直接修改好一点
            List<Category> categories = childCategory.stream().map(child -> {
                Category category = new Category();
                BeanUtils.copyProperties(child, category);
                category.setParentId(id);
                return category;
            }).toList();
            boolean bool = this.updateBatchById(categories);
            ThrowUtils.throwIf(!bool, ReturnCodeEnum.OPERATION_ERROR, "修改异常！");
        }
        Category category = new Category();
        BeanUtils.copyProperties(dto, category);
        Integer result = this.getBaseMapper().updateById(category);
        return null != result && result >= 1;
    }

    @Override
    public List<CategoryVO> getCategoryWithChild() {
        return categoryMapper.selectCategoryWithChild();
    }

    @Override
    public List<Long> getAllId() {
        List<Category> categories = this.getBaseMapper().selectList(null);
        return categories.stream().map(category -> category.getId()).toList();
    }

    @Override
    public List<CategoryCascaderVO> getCategoryCascaderVO() {

        return this.getBaseMapper().selectCategoryCascaderVO();
    }

    @Override
    public QueryWrapper<Category> getPageQueryWrapper(CategoryPageQueryDTO dto) {
        if (Objects.isNull(dto)) {
            return null;
        }

        // 获取dto属性，并构造查询条件器
        Long id = dto.getId();
        String categoryName = dto.getCategoryName();
        Long parentId = dto.getParentId();

        QueryWrapper<Category> qw = new QueryWrapper<>();
        qw.like(Objects.nonNull(id), "id", id);
        qw.like(Objects.nonNull(parentId), "parent_id", parentId);
        qw.like(StringUtils.isNotBlank(categoryName), "category_name", categoryName);

        return qw;
    }

    @Override
    public PageResult getPageWithChildren(CategoryPageQueryDTO dto) {
        String categoryName = dto.getCategoryName();
        categoryName = "".equals(categoryName) ? null : categoryName;
        Long id = dto.getId();
        if (ObjectUtils.anyNotNull(categoryName, id)) {
            QueryWrapper<Category> qw = new QueryWrapper<>();
            qw.like(StringUtils.isNotBlank(categoryName),"category_name", categoryName);
            qw.like(Objects.nonNull(id), "id", id);
            Page<Category> categoryPage = this.getBaseMapper().selectPage(
                    new Page<>(dto.getCurrent(), dto.getPageSize()), qw);
            List<Category> records = categoryPage.getRecords();
            if (CollectionUtil.isEmpty(records)) {
                return PageResult.builder()
                        .total(categoryPage.getTotal())
                        .records(Collections.emptyList())
                        .build();
            }
            List<CategoryVO> categoryVOList = records.stream().map(category -> {
                CategoryVO categoryVO = new CategoryVO();
                BeanUtils.copyProperties(category, categoryVO);
                return categoryVO;
            }).toList();
            return PageResult.builder()
                    .total(categoryPage.getTotal())
                    .records(categoryVOList)
                    .build();
        }
        Page<CategoryVO> page = this.getBaseMapper()
                .selectPageWithChildren(new Page<>(dto.getCurrent(), dto.getPageSize()),
                        dto);
        return PageResult.builder()
                .total(page.getTotal())
                .records(page.getRecords())
                .build();
    }

    @Override
    public List<CategoryVO> getTopCategory() {
        QueryWrapper<Category> qw = new QueryWrapper<>();
        qw.eq("parent_id", CategoryConstant.TOP_CATEGORY_PARENT_ID);
        List<Category> list = this.getBaseMapper().selectList(qw);
        return list.stream().map(category -> {
            CategoryVO categoryVO = new CategoryVO();
            BeanUtils.copyProperties(category, categoryVO);
            return categoryVO;
        }).collect(Collectors.toList());
    }

    @Override
    public CategoryVO getByIdWithParent(Long id) {
        ThrowUtils.throwIf(Objects.isNull(id) || id <= 0, ReturnCodeEnum.PARAMS_ERROR);
        return this.getBaseMapper().selectCategoryWithChildById(id);
    }
}




